home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Games Collection 1 / software vault.zip / software vault / CDR10 / YICN23.ZIP / UNITS / ICON.CPP < prev    next >
C/C++ Source or Header  |  1993-02-21  |  14KB  |  441 lines

  1. #include <fstream.h>
  2. #include <stdio.h>
  3. #include <conio.h>
  4. #include <string.h>
  5. #include <mem.h>
  6. #include <dos.h>
  7. #include <alloc.h>
  8. #include <io.h>
  9. #include <stdlib.h>
  10. #include "xlib.h"
  11. #include "xrect.h"
  12. #include "xpbitmap.h"
  13. #include "xcbitmap.h"
  14. #include "xpal.h"
  15. #include "icon.h"
  16.  
  17. int widthFour(int width)
  18. {
  19.   return (width + (((4-(width % 4)) == 4) ? 0 : (4-(width%4))));  //smallest mult of 4 > width!
  20. }
  21.  
  22. char * unRollBlt(char * rolledBlt, int & iwidth, int & iheight)
  23. {
  24.   char * temp = NULL;
  25.   int * width = (int *)&rolledBlt[0];
  26.   iwidth = *width;
  27.   int * height = (int *)&rolledBlt[2];
  28.   iheight = *height;
  29.   char * tempimage = &rolledBlt[4];
  30.   int row, col, i, j, k, width4;
  31.   int heightCounter, widthCounter;
  32.   width4 = widthFour(*width);
  33.   int newHeight = *height;
  34.   temp = new char[width4*newHeight + 4];
  35.   if (temp == NULL) {delete temp; return NULL;}
  36.   temp[0] = (width4)/4;
  37.   temp[1] = *height;
  38.   k = 2;
  39.   for (i=0; i<4; i++)
  40.     for (heightCounter = 0; heightCounter < *height; heightCounter +=1)
  41.       for (widthCounter=0; widthCounter < width4; widthCounter += 4, k++)
  42.     {
  43.     if (((widthCounter + i) >= *width))
  44.     temp[k] = 0;
  45.     else
  46.     temp[k] = tempimage[i + (heightCounter* *width) + widthCounter];
  47.     }
  48.   return (char far *)temp;
  49. }
  50.  
  51. char * rollBlt(char * unRolledBlt, int & iwidth, int &iheight)
  52. {
  53.   int width4 = 4*unRolledBlt[0];
  54.   int height = unRolledBlt[1];
  55.   char *returnBuffer = new char [iwidth * iheight + 4];
  56.   if (returnBuffer == NULL)
  57.     return NULL;
  58.   *(int *)&returnBuffer[0] = iwidth;
  59.   *(int *)&returnBuffer[2] = iheight;
  60.   int k = 2;
  61.   for (int i = 0; i < 4; ++i)  //each of the four loops!
  62.     for(int heightCounter = 0; heightCounter < height; ++heightCounter)
  63.       for(int widthCounter = 0; widthCounter < width4; widthCounter += 4)
  64.       {
  65.     if (widthCounter + i < iwidth)
  66.       returnBuffer[i + heightCounter*iwidth + widthCounter + 4] = unRolledBlt[k];
  67.     k++;
  68.       }
  69.   return(returnBuffer);
  70. }
  71.  
  72. char far *
  73. AllocatedSprite(int logicalWidth, char * bitmap)
  74. {
  75.     char * result;
  76.     int size;
  77.  
  78.     result = new char[(bitmap[0] * bitmap[1] * 7) / 2 + 25];
  79.     if (result == 0)
  80.       return(0);
  81.     size = x_compile_bitmap(logicalWidth, bitmap, result);
  82.  
  83.     return (char far *)farrealloc(result, size);
  84. }
  85.  
  86.  
  87. byte icon::getPixel(int x, int y)
  88. {
  89.   int width4 = 4*unrolledPic[0];
  90.   return unrolledPic[((x % 4)*(width4*height/4) + x/4 + y*width4/4) +2 ];
  91. }
  92.  
  93. void icon::hide(int x, int y, word toOffset, word fromOffset)
  94. {
  95.   x_cp_vid_rect(x, y, x+(width), y+height, x, y,
  96.     fromOffset, toOffset,
  97.     ScrnLogicalPixelWidth,ScrnLogicalPixelWidth);
  98. }
  99.  
  100. void icon::show(int x, int y, word offset)
  101. {
  102.   if (unrolledPic != NULL)
  103.   {
  104.     if (flags == normal)
  105.       x_put_pbm(x, y, offset, unrolledPic);
  106.     else if (flags == fast)
  107.       x_put_cbitmap(x, y, offset, unrolledPic);
  108.   }
  109. }
  110.  
  111. void icon::showMasked(int x, int y, word offset)
  112. {
  113.   if (unrolledPic != NULL)
  114.   {
  115.     if (flags == normal)
  116.       x_put_masked_pbm(x, y, offset, unrolledPic);
  117.     else if (flags == fast)
  118.       x_put_cbitmap(x, y, offset, unrolledPic);
  119.   }
  120. }
  121.  
  122. void icon::save(char * filename)
  123. {
  124.   long miscNumber = 0;
  125.   long bufferIndex = 0;
  126.   if (flags != fast)
  127.   {
  128.     ofstream myOutStream(filename, ios::out | ios::binary);
  129.     if (myOutStream)
  130.     {
  131.       myOutStream.write("YARFILE   ", 10);
  132.       myOutStream.write((char *) &width, sizeof(width));
  133.       myOutStream.write((char *) &height, sizeof(height));
  134.       int width4 = widthFour(width);
  135.       for (long bytesLeft = (long)width4 * (long)height + 2; bytesLeft > 0;)//
  136.       {
  137.     miscNumber = (bytesLeft < 32000) ? bytesLeft : 32000;
  138.     myOutStream.write(unrolledPic + bufferIndex, (int)miscNumber);
  139.     bytesLeft -= miscNumber;
  140.     bufferIndex += miscNumber;
  141.       }
  142.       myOutStream.close();
  143.     }
  144.   }
  145. }
  146.  
  147. char *icon::useData(unsigned char * myPointer, flagType iflags)
  148. //for use with bin2hdr files!!
  149. {
  150.   if (unrolledPic)
  151.     delete unrolledPic;
  152.   flags = iflags;
  153.   width = *(int *) &myPointer[10];
  154.   height = *(int *) &myPointer[12];
  155.   if (flags == normal)
  156.   {
  157.     int width4 = widthFour(width);
  158.     unrolledPic = new char[width4 * height + 2];//
  159.     memcpy(unrolledPic, &myPointer[14], (width4 * height + 2));//
  160.     makeCollisionMap();
  161.     return(unrolledPic);
  162.   }
  163.   else if (flags == fast)
  164.   {
  165.     char * tempRolled = rollBlt(myPointer + 14, width, height);
  166.     tempRolled[2] = (char) width;
  167.     tempRolled[3] = (char) height;
  168.     unrolledPic = AllocatedSprite(ScrnLogicalPixelWidth/4, tempRolled + 2);
  169.     delete tempRolled;
  170.     makeCollisionMap();
  171.     return(unrolledPic);
  172.   }
  173.   else return(NULL);
  174. }
  175.  
  176. char * icon::load(char * filename, flagType iflags, yakLib * myYakLib)
  177. {
  178.   char * tempBuffer = NULL;
  179.   if (myYakLib)
  180.     tempBuffer = myYakLib->loadToMem(filename);
  181.   else
  182.     tempBuffer = loadDosToMem(filename);
  183.   if ((tempBuffer == NULL) || (strncmp(tempBuffer, "YARFILE", 7)))
  184.   {
  185.     unrolledPic = NULL;
  186.     return(NULL);
  187.   }
  188.   else
  189.   {
  190.     char* tempReturnValue = useData(tempBuffer, iflags);
  191.     delete tempBuffer;
  192.     return tempReturnValue;
  193.   }
  194. }
  195.  
  196. //collision code goes in here.
  197.  
  198. //the cbox map array is in [y][x] format, in order to use the more elegant
  199. //and very fast bitwise operators.  This is contrary to the familiar icon
  200. //bitmap [x][y] structure.
  201.  
  202. int icon::setWPacked(int xwid, int y1)
  203. {
  204.   int x8 = (xwid >> 3) + ((xwid & 7) > 0);
  205.   if (collisionMap) delete collisionMap;
  206.   collisionMap = new byte[x8 * y1];
  207.   if (collisionMap == NULL)
  208.     return 0;
  209.   else
  210.     byteWidth = x8;
  211.   return 1;
  212. }
  213.  
  214. int icon::setCollisionBit(int ix, int iy, booleanFlags flag)
  215. {
  216.   byte bitPixel = 128; // ie 1000 0000
  217.   bitPixel >>= ix % 8; // right shift it...
  218.   if (flag == on)
  219.     collisionMap[iy * byteWidth + (int)(ix/8)] |= bitPixel;
  220.   else if (flag == off)
  221.     collisionMap[iy * byteWidth + (int)(ix/8)] &= ~bitPixel;
  222.   return bitPixel;
  223. }
  224.  
  225. int icon::getCollisionBit(int ix, int iy)
  226. {
  227.   byte bitPixel = 128;
  228.   bitPixel >>= ix%8;
  229.   return (collisionMap[iy * byteWidth + (int)(ix/8)] & bitPixel) ? 1 : 0;
  230. }
  231.  
  232. void icon::spewCollisionTable(void)
  233. {
  234.   for (int heightCounter = 0; heightCounter < height; ++heightCounter)
  235.   {
  236.     for (int widthCounter = 0; widthCounter < byteWidth*8; ++widthCounter)
  237.       cout << getCollisionBit(widthCounter, heightCounter);
  238.     cout << '\n';
  239.   }
  240. }
  241.  
  242.  
  243. int icon::makeCollisionMap()
  244. {
  245.   setWPacked(width, height);
  246.   for (int heightCounter = 0; heightCounter < height; ++heightCounter)
  247.     for (int widthCounter = 0; widthCounter < byteWidth*8; ++widthCounter)
  248.       setCollisionBit(widthCounter, heightCounter, (getPixel(widthCounter, heightCounter) == 0) ? off : on);
  249.   return 1;
  250. }
  251.  
  252. int icon::hitXY(int myX, int myY, icon* target, int targetX, int targetY)
  253. {
  254.   int overlapTop = (myY > targetY) ? myY : targetY;
  255.   int overlapBottom = (myY+height > targetY + target->height) ?
  256.                          (targetY + target->height) :
  257.                          (myY + height);
  258.   if (overlapTop > overlapBottom) return 0;
  259.   int overlapLeft = (myX > targetX) ? myX : targetX;
  260.   int overlapRight = (myX + width > targetX + target->width) ?
  261.                          (targetX + target->width) :
  262.                          (myX + width);
  263.   int overlapWidth = overlapRight - overlapLeft;
  264.   if (overlapWidth < 0) return 0;
  265.   int overlapByteWidth = (overlapWidth >> 3) + ((overlapWidth & 7) > 0);
  266.   //now we know what the tops and bottoms of the overlap are.  Now our
  267.   //task is to find the offsets in each collisionMap to start checking.
  268.   byte * myOffset = collisionMap, * targetOffset = target->collisionMap;
  269.   myOffset += (myY > targetY) ? 0 : byteWidth*(overlapTop - myY); //y part
  270.   myOffset += (myX > targetX) ? 0 : (overlapLeft - myX) >> 3;
  271.   targetOffset += (targetY > myY) ? 0 : target->byteWidth*(overlapTop - targetY);
  272.   targetOffset += (targetX > myX) ? 0 : (overlapLeft - targetY) >> 3;
  273.   int myStep = byteWidth - overlapByteWidth;
  274.   int targetStep = target->byteWidth - overlapByteWidth;
  275.  
  276.   int shift = (7 - (overlapWidth & 7));
  277.  
  278.   for (int heightCounter = overlapTop; heightCounter <= overlapBottom; ++heightCounter)
  279.   {
  280.     for (int widthCounter = 0; widthCounter < overlapByteWidth; ++ widthCounter)
  281.     {
  282.       if ((myX < targetX) ?
  283.           (*myOffset & (*targetOffset >> shift)) :
  284.           (*myOffset & (*targetOffset << shift))) return 1;
  285.       ++myOffset;
  286.       ++targetOffset;
  287.     }
  288.     myOffset += myStep;
  289.     targetOffset += targetStep;
  290.   }
  291.  
  292.   return 0;
  293. }
  294.  
  295.  
  296.  
  297. //icon zooming code goes here----------------------------------------->
  298.  
  299. byte ** icon::zoomTable = NULL;
  300. int icon::zoomTableWidth = 0;
  301.  
  302. byte ** icon::setZoomTable(int newWidth)
  303. {
  304.   float interval = 0;
  305.   float tempNumber = 0, secondTempNumber = 0;
  306.   if (zoomTable)
  307.     delete zoomTable;
  308.   zoomTable = new byte*[newWidth];
  309.   if (!zoomTable) return NULL;
  310.   for (int counter = 0; counter < newWidth; ++counter)
  311.     zoomTable[counter] = new byte[newWidth];
  312.   if (!zoomTable[newWidth - 1]) return NULL;
  313.   zoomTableWidth = newWidth;
  314.   for (int heightCounter = 0; heightCounter < newWidth; ++heightCounter)
  315.   {
  316.     interval = (((float)newWidth) / ((float)heightCounter+1)); //+1 for div by 0
  317.     tempNumber = secondTempNumber = 0;
  318.     for (int widthCounter = 0; widthCounter < newWidth; ++widthCounter)
  319.     {
  320.       secondTempNumber = ((float)widthCounter + 1) / interval;
  321.       if ((secondTempNumber - tempNumber) >= 1)
  322.       {
  323.         zoomTable[heightCounter][widthCounter] = 1;
  324.         tempNumber += 1;
  325.       }
  326.       else
  327.         zoomTable[heightCounter][widthCounter] = 0;
  328.     }
  329.   }
  330.   return zoomTable;
  331. }
  332.  
  333. void icon::spewZoomTable(void)
  334. {
  335.   for (int heightCounter = 0; heightCounter < zoomTableWidth; ++heightCounter)
  336.   {
  337.     for (int widthCounter = 0; widthCounter < zoomTableWidth; ++widthCounter)
  338.       cout << (int)zoomTable[heightCounter][widthCounter];
  339.     cout << '\n';
  340.   }
  341. }
  342.  
  343. icon * icon::zoomedIcon(int newWidth)
  344. {
  345.   int numberOfDots = newWidth / zoomTableWidth; //number of times each dot is drawn
  346.   int tempPosition = newWidth % zoomTableWidth - 1; //position in zoom table
  347.   if (tempPosition < 0)
  348.   {
  349.     numberOfDots--;
  350.     tempPosition = zoomTableWidth - 1;
  351.   }
  352.   byte * zoomReference = zoomTable[tempPosition];
  353.   int width4 = widthFour(newWidth);
  354.   byte * zoomedIcon = new byte[width4 * newWidth + 2];
  355.   if (!zoomedIcon)
  356.     return NULL;
  357.   *(byte *)&zoomedIcon[0] = (byte)(widthFour(newWidth)/4);
  358.   *(byte *)&zoomedIcon[1] = (byte)(newWidth);
  359.   byte * currentZoomedPointer = zoomedIcon+2; //current position in new buffer
  360.   byte * currentUnzoomedPointer = unrolledPic+2;
  361.   int zoomedFourCounter = 0; //what step of the four strings we're on
  362.   int unzoomedFourCounter = 0;
  363.   int zoomedInterval = (zoomedIcon[0]*zoomedIcon[1]); //how much to increment
  364.   int zoomedInterval4 = 4*zoomedInterval;
  365.   int unzoomedInterval = (unrolledPic[0]*unrolledPic[1]); //our pointers
  366.   int unzoomedInterval4 = 4*unzoomedInterval;
  367.   byte * tempLinePointer = NULL; //we need this to duplicate lines
  368.   int heightCounter, widthCounter, lineCounter, dotCounter;
  369.   int dotsDone = 0;
  370.   int linesDone = 0;
  371.   for (heightCounter = 0; heightCounter < zoomTableWidth; ++heightCounter)
  372.   {
  373.     for (lineCounter = 0,tempLinePointer = currentUnzoomedPointer; lineCounter < (numberOfDots + zoomReference[heightCounter]); ++lineCounter)
  374.     {
  375.       ++linesDone;
  376.       currentUnzoomedPointer = tempLinePointer;
  377.       dotsDone = 0;
  378.       for (widthCounter = 0; widthCounter < zoomTableWidth; ++widthCounter)
  379.       {
  380.         for (dotCounter = 0; dotCounter < (numberOfDots + zoomReference[widthCounter]); ++dotCounter)
  381.         {
  382.           *currentZoomedPointer = *currentUnzoomedPointer;
  383.           zoomedFourCounter++;
  384.           currentZoomedPointer += zoomedInterval;
  385.           if (zoomedFourCounter == 4)
  386.           {
  387.             zoomedFourCounter = 0;
  388.             currentZoomedPointer -= (zoomedInterval4 - 1);
  389.           }
  390.           ++dotsDone;
  391.         }
  392.         unzoomedFourCounter++;
  393.         currentUnzoomedPointer += unzoomedInterval;
  394.         if (unzoomedFourCounter == 4)
  395.         {
  396.           unzoomedFourCounter = 0;
  397.           currentUnzoomedPointer -= (unzoomedInterval4 - 1);
  398.         }
  399.       }
  400.       for (;dotsDone < width4; ++dotsDone)
  401.       {
  402.         *currentZoomedPointer = 0;
  403.         zoomedFourCounter++;
  404.         currentZoomedPointer += zoomedInterval;
  405.         if (zoomedFourCounter == 4)
  406.         {
  407.           zoomedFourCounter = 0;
  408.           currentZoomedPointer -= (zoomedInterval4 - 1);
  409.         }
  410.       }
  411.     }
  412.     currentUnzoomedPointer = tempLinePointer + unrolledPic[0];
  413.   }
  414.   for (;linesDone < newWidth; ++linesDone)
  415.   {
  416.     for (dotsDone = 0; dotsDone < width4; ++dotsDone)
  417.     {
  418.       *currentZoomedPointer = 0;
  419.       zoomedFourCounter++;
  420.       currentZoomedPointer += zoomedInterval;
  421.       if (zoomedFourCounter == 4)
  422.       {
  423.         zoomedFourCounter = 0;
  424.         currentZoomedPointer -= (zoomedInterval4 - 1);
  425.       }
  426.     }
  427.   }
  428.   icon * returnIcon = new icon;
  429.   returnIcon->unrolledPic = zoomedIcon;
  430.   returnIcon->flags = icon::normal;
  431.   returnIcon->width = returnIcon->height = newWidth;
  432.   returnIcon->collisionMap = NULL;
  433.   return returnIcon;
  434. }
  435.  
  436. void icon::showZoomed(int x, int y, word offset, int newWidth)
  437. {
  438.   icon * tempIcon = zoomedIcon(newWidth);
  439.   tempIcon->showMasked(x, y, offset);
  440.   delete tempIcon;
  441. }